package cn.chengpengper.threadpool;


import cn.chengpengper.rpc.constants.RpcConstants;

import java.util.Objects;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @author huchengpeng
 */
public class ConcurrentThreadPool {

    private ThreadPoolExecutor threadPoolExecutor;

    private static volatile ConcurrentThreadPool instance;

    private ConcurrentThreadPool() {
    }

    private ConcurrentThreadPool(int corePoolSize, int maxNumPoolSize) {
        if (corePoolSize <= 0) {
            corePoolSize = RpcConstants.DEFAULT_CORE_POOL_SIZE;
        }
        if (maxNumPoolSize <= 0) {
            maxNumPoolSize = RpcConstants.DEFAULT_MAXI_NUM_POOL_SIZE;
        }
        if (corePoolSize > maxNumPoolSize) {
            maxNumPoolSize = corePoolSize;
        }
        this.threadPoolExecutor = new ThreadPoolExecutor(corePoolSize, maxNumPoolSize, RpcConstants.DEFAULT_KEEP_ALIVE_TIME, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(RpcConstants.DEFAULT_QUEUE_CAPACITY));
    }

    public static ConcurrentThreadPool getInstance(int corePoolSize, int maxNumPoolSize) {
        if (Objects.isNull(instance)) {
            synchronized (ConcurrentThreadPool.class) {
                if (Objects.isNull(instance)) {
                    instance = new ConcurrentThreadPool(corePoolSize, maxNumPoolSize);
                }
            }
        }
        return instance;
    }

    public void submit(Runnable task) {
        threadPoolExecutor.submit(task);
    }

    public void stop() {
        threadPoolExecutor.shutdown();
    }
}
